Web Workers实现javascript多线程

大家可能都知道javascript是单线程。但在HTML5中新增与线程相关的一个API,Web Workers可以实现Web平台上多线程处理的功能。Web Worker为Web内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。

我们需要把希望单独执行的javascript代码放到一个单独的js文件中,然后在页面中调用Worker构造函数来创建一个线程,参数是该文件路径,参数存放如果是相对地址,那么要以包含调用Worker构造函数语句所在脚本为参照,如果是绝对路径,需要保证同源(协议+主机+端口)。这个文件不需要我们在页面使用script标签显示引用

创建一个新的 worker 十分简单。你所要做的就是调用 Worker() 构造函数,指定一个要在 worker 线程内运行的脚本的 URI

1
2
3
4
5
var myWorker = new Worker("my_task.js");

myWorker.onmessage = function (oEvent) {
console.log("Called back by the worker!\n");
};

或者,你也可以使用 addEventListener():

1
2
3
4
5
6
7
var myWorker = new Worker("my_task.js");

myWorker.addEventListener("message", function (oEvent) {
console.log("Called back by the worker!\n");
}, false);

myWorker.postMessage(""); // start the worker.

worker对象只有两个属性

  • onerror:当worker运行出现错误,并且没有在worker中ing捕获,会在此捕获
  • onmessage:当worker向主线程发送消息是调用

在其prototype内有两个重要方法

  • postMessage:很熟悉的赶脚,之前我们介绍过window对象的postMessage()方法,woker的postMessage方法和window的比较类似,但参数略有不同,只需要传递消息内容就可以,而且支持所有JavaScript原生数据类型,当然不放心的话同样也可以序列化为字符串传递
  • terminate:终止worker执行,有些worker执行比较慢,主线程可以主动终止其执行

worker.onmessage
在这个句柄内接收外部调用者传递的参数,参数可以通过e.data获取。即获取子线程中postMessage时方法传来的数据。

在worker中不能使用window对象和docuemnt对象。
但可以使用这些:

  • JavaScript的全局对象:JSON、Date()、Array
  • self自身引用
  • location对象,但是其属性都是只读的,改了也影响不到调用者
  • navigator对象
  • setTimeout()、setInterval()及其对应清除方法
  • addEventListener()、removeEventListener()